home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Unix / Communication / zmodem / Source / rbsb.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-21  |  6.7 KB  |  324 lines

  1. /*
  2.  *
  3.  *  Rev 5-09-89
  4.  *  This file contains Unix specific code for setting terminal modes,
  5.  *  very little is specific to ZMODEM or YMODEM per se (that code is in
  6.  *  sz.c and rz.c).  The CRC-16 routines used by XMODEM, YMODEM, and ZMODEM
  7.  *  are also in this file, a fast table driven macro version
  8.  *
  9.  *    V7/BSD HACKERS:  SEE NOTES UNDER mode(2) !!!
  10.  *
  11.  *   This file is #included so the main file can set parameters such as HOWMANY.
  12.  *   See the main files (rz.c/sz.c) for compile instructions.
  13.  */
  14.  
  15. #ifdef V7
  16. #include <sys/types.h>
  17. #include <sys/stat.h>
  18. #define STAT
  19. #include <sgtty.h>
  20. #define OS "V7/BSD"
  21. #define ROPMODE "r"
  22. #ifdef LLITOUT
  23. long Locmode;        /* Saved "local mode" for 4.x BSD "new driver" */
  24. long Locbit = LLITOUT;    /* Bit SUPPOSED to disable output translations */
  25. #include <strings.h>
  26. #endif
  27. #endif
  28.  
  29. #ifndef OS
  30. #ifndef USG
  31. #define USG
  32. #endif
  33. #endif
  34.  
  35. #ifdef USG
  36. #include <sys/types.h>
  37. #include <sys/stat.h>
  38. #define STAT
  39. #include <termio.h>
  40. #define OS "SYS III/V"
  41. #define ROPMODE "r"
  42. #define MODE2OK
  43. #include <string.h>
  44. #endif
  45.  
  46. #if HOWMANY  > 255
  47. Howmany must be 255 or less
  48. #endif
  49.  
  50. /*
  51.  * return 1 iff stdout and stderr are different devices
  52.  *  indicating this program operating with a modem on a
  53.  *  different line
  54.  */
  55. int Fromcu;        /* Were called from cu or yam */
  56. from_cu()
  57. {
  58.     struct stat a, b;
  59.  
  60.     fstat(1, &a); fstat(2, &b);
  61.     Fromcu = a.st_rdev != b.st_rdev;
  62.     return;
  63. }
  64. cucheck()
  65. {
  66.     if (Fromcu)
  67.         fprintf(stderr,"Please read the manual page BUGS chapter!\r\n");
  68. }
  69.  
  70.  
  71. struct {
  72.     unsigned baudr;
  73.     int speedcode;
  74. } speeds[] = {
  75.     110,    B110,
  76.     300,    B300,
  77.     600,    B600,
  78.     1200,    B1200,
  79.     2400,    B2400,
  80.     4800,    B4800,
  81.     9600,    B9600,
  82.     19200,    EXTA,
  83.     38400,    EXTB,
  84.     0,
  85. };
  86.  
  87. int Twostop;        /* Use two stop bits */
  88.  
  89.  
  90. /*
  91.  *  The following uses an external rdchk() routine if available,
  92.  *  otherwise defines the function for BSD or fakes it for SYSV.
  93.  */
  94.  
  95. #ifndef READCHECK
  96. #ifdef FIONREAD
  97. #define READCHECK
  98. /*
  99.  *  Return non 0 iff something to read from io descriptor f
  100.  */
  101. rdchk(f)
  102. {
  103.     static long lf;
  104.  
  105.     ioctl(f, FIONREAD, &lf);
  106.     return ((int) lf);
  107. }
  108.  
  109. #else        /* FIONREAD */
  110.  
  111. #ifdef SV
  112. #define READCHECK
  113. #include <fcntl.h>
  114.  
  115. int checked = 0;
  116. /*
  117.  * Nonblocking I/O is a bit different in System V, Release 2
  118.  *  Note: this rdchk vsn throws away a byte, OK for ZMODEM
  119.  *  sender because protocol design anticipates this problem.
  120.  */
  121. #define EATSIT
  122. rdchk(f)
  123. {
  124.     int lf, savestat;
  125.     static char bchecked;
  126.  
  127.     savestat = fcntl(f, F_GETFL) ;
  128.     fcntl(f, F_SETFL, savestat | O_NDELAY) ;
  129.     lf = read(f, &bchecked, 1) ;
  130.     fcntl(f, F_SETFL, savestat) ;
  131.     checked = bchecked & 0377;    /* force unsigned byte */
  132.     return(lf) ;
  133. }
  134. #endif
  135. #endif
  136. #endif
  137.  
  138.  
  139. static unsigned
  140. getspeed(code)
  141. {
  142.     register n;
  143.  
  144.     for (n=0; speeds[n].baudr; ++n)
  145.         if (speeds[n].speedcode == code)
  146.             return speeds[n].baudr;
  147.     return 38400;    /* Assume fifo if ioctl failed */
  148. }
  149.  
  150.  
  151.  
  152. struct sgttyb oldtty, tty;
  153. struct tchars oldtch, tch;
  154.  
  155. /*
  156.  * mode(n)
  157.  *  3: save old tty stat, set raw mode with flow control
  158.  *  2: set XON/XOFF for sb/sz with ZMODEM or YMODEM-g
  159.  *  1: save old tty stat, set raw mode 
  160.  *  0: restore original tty mode
  161.  */
  162. mode(n)
  163. {
  164.     static did0 = FALSE;
  165.  
  166.     vfile("mode:%d", n);
  167.     switch(n) {
  168. #ifdef USG
  169.     case 2:        /* Un-raw mode used by sz, sb when -g detected */
  170.         if(!did0)
  171.             (void) ioctl(0, TCGETA, &oldtty);
  172.         tty = oldtty;
  173.  
  174.         tty.c_iflag = BRKINT|IXON;
  175.  
  176.         tty.c_oflag = 0;    /* Transparent output */
  177.  
  178.         tty.c_cflag &= ~PARENB;    /* Disable parity */
  179.         tty.c_cflag |= CS8;    /* Set character size = 8 */
  180.         if (Twostop)
  181.             tty.c_cflag |= CSTOPB;    /* Set two stop bits */
  182.  
  183.  
  184. #ifdef READCHECK
  185.         tty.c_lflag = Zmodem ? 0 : ISIG;
  186.         tty.c_cc[VINTR] = Zmodem ? -1:030;    /* Interrupt char */
  187. #else
  188.         tty.c_lflag = ISIG;
  189.         tty.c_cc[VINTR] = Zmodem ? 03:030;    /* Interrupt char */
  190. #endif
  191.         tty.c_cc[VQUIT] = -1;            /* Quit char */
  192. #ifdef NFGVMIN
  193.         tty.c_cc[VMIN] = 1;
  194. #else
  195.         tty.c_cc[VMIN] = 3;     /* This many chars satisfies reads */
  196. #endif
  197.         tty.c_cc[VTIME] = 1;    /* or in this many tenths of seconds */
  198.  
  199.         (void) ioctl(0, TCSETAW, &tty);
  200.         did0 = TRUE;
  201.         return OK;
  202.     case 1:
  203.     case 3:
  204.         if(!did0)
  205.             (void) ioctl(0, TCGETA, &oldtty);
  206.         tty = oldtty;
  207.  
  208.         tty.c_iflag = n==3 ? (IGNBRK|IXOFF) : IGNBRK;
  209.  
  210.          /* No echo, crlf mapping, INTR, QUIT, delays, no erase/kill */
  211.         tty.c_lflag &= ~(ECHO | ICANON | ISIG);
  212.  
  213.         tty.c_oflag = 0;    /* Transparent output */
  214.  
  215.         tty.c_cflag &= ~PARENB;    /* Same baud rate, disable parity */
  216.         tty.c_cflag |= CS8;    /* Set character size = 8 */
  217.         if (Twostop)
  218.             tty.c_cflag |= CSTOPB;    /* Set two stop bits */
  219. #ifdef NFGVMIN
  220.         tty.c_cc[VMIN] = 1; /* This many chars satisfies reads */
  221. #else
  222.         tty.c_cc[VMIN] = HOWMANY; /* This many chars satisfies reads */
  223. #endif
  224.         tty.c_cc[VTIME] = 1;    /* or in this many tenths of seconds */
  225.         (void) ioctl(0, TCSETAW, &tty);
  226.         did0 = TRUE;
  227.         Effbaud = Baudrate = getspeed(tty.c_cflag & CBAUD);
  228.         return OK;
  229. #endif
  230. #ifdef V7
  231.     /*
  232.      *  NOTE: this should transmit all 8 bits and at the same time
  233.      *   respond to XOFF/XON flow control.  If no FIONREAD or other
  234.      *   rdchk() alternative, also must respond to INTRRUPT char
  235.      *   This doesn't work with V7.  It should work with LLITOUT,
  236.      *   but LLITOUT was broken on the machine I tried it on.
  237.      */
  238.     case 2:        /* Un-raw mode used by sz, sb when -g detected */
  239.         if(!did0) {
  240.             ioctl(0, TIOCEXCL, 0);
  241.             ioctl(0, TIOCGETP, &oldtty);
  242.             ioctl(0, TIOCGETC, &oldtch);
  243. #ifdef LLITOUT
  244.             ioctl(0, TIOCLGET, &Locmode);
  245. #endif
  246.         }
  247.         tty = oldtty;
  248.         tch = oldtch;
  249. #ifdef READCHECK
  250.         tch.t_intrc = Zmodem ? -1:030;    /* Interrupt char */
  251. #else
  252.         tch.t_intrc = Zmodem ? 03:030;    /* Interrupt char */
  253. #endif
  254.         tty.sg_flags |= (ODDP|EVENP|CBREAK);
  255.         tty.sg_flags &= ~(ALLDELAY|CRMOD|ECHO|LCASE);
  256.         ioctl(0, TIOCSETP, &tty);
  257.         ioctl(0, TIOCSETC, &tch);
  258. #ifdef LLITOUT
  259.         ioctl(0, TIOCLBIS, &Locbit);
  260. #endif
  261.         bibi(99);    /* un-raw doesn't work w/o lit out */
  262.         did0 = TRUE;
  263.         return OK;
  264.     case 1:
  265.     case 3:
  266.         if(!did0) {
  267.             ioctl(0, TIOCEXCL, 0);
  268.             ioctl(0, TIOCGETP, &oldtty);
  269.             ioctl(0, TIOCGETC, &oldtch);
  270. #ifdef LLITOUT
  271.             ioctl(0, TIOCLGET, &Locmode);
  272. #endif
  273.         }
  274.         tty = oldtty;
  275.         tty.sg_flags |= (RAW|TANDEM);
  276.         tty.sg_flags &= ~ECHO;
  277.         ioctl(0, TIOCSETP, &tty);
  278.         did0 = TRUE;
  279.         Effbaud = Baudrate = getspeed(tty.sg_ospeed);
  280.         return OK;
  281. #endif
  282.     case 0:
  283.         if(!did0)
  284.             return ERROR;
  285. #ifdef USG
  286.         (void) ioctl(0, TCSBRK, 1);    /* Wait for output to drain */
  287.         (void) ioctl(0, TCFLSH, 1);    /* Flush input queue */
  288.         (void) ioctl(0, TCSETAW, &oldtty);    /* Restore modes */
  289.         (void) ioctl(0, TCXONC,1);    /* Restart output */
  290. #endif
  291. #ifdef V7
  292.         ioctl(0, TIOCSETP, &oldtty);
  293.         ioctl(0, TIOCSETC, &oldtch);
  294.         ioctl(0, TIOCNXCL, 0);
  295. #ifdef LLITOUT
  296.         ioctl(0, TIOCLSET, &Locmode);
  297. #endif
  298. #endif
  299.  
  300.         return OK;
  301.     default:
  302.         return ERROR;
  303.     }
  304. }
  305.  
  306. sendbrk()
  307. {
  308. #ifdef V7
  309. #ifdef TIOCSBRK
  310. #define CANBREAK
  311.     sleep(1);
  312.     ioctl(0, TIOCSBRK, 0);
  313.     sleep(1);
  314.     ioctl(0, TIOCCBRK, 0);
  315. #endif
  316. #endif
  317. #ifdef USG
  318. #define CANBREAK
  319.     ioctl(0, TCSBRK, 0);
  320. #endif
  321. }
  322.  
  323. /* End of rbsb.c */
  324.